package cn.edu.xaut.mybatisers.mall.ServiceImp;

import cn.edu.xaut.mybatisers.mall.Dao.RegisterDao;
import cn.edu.xaut.mybatisers.mall.Entity.Consumer;
import cn.edu.xaut.mybatisers.mall.Exception.ExceptionEntity.LoginException;
import cn.edu.xaut.mybatisers.mall.Exception.ExceptionEntity.NotMemberException;
import cn.edu.xaut.mybatisers.mall.Exception.ExceptionEntity.ParametersIncompleteException;
import cn.edu.xaut.mybatisers.mall.Exception.ExceptionEntity.TeleNumberExistException;
import cn.edu.xaut.mybatisers.mall.Service.RegisterService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpRequest;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.nio.charset.StandardCharsets;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

@Service
@SuppressWarnings("all")
public class RegisterServiceImp implements RegisterService {
    private static Logger logger = Logger.getLogger(RegisterDao.class);

    private char code[] = {'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'i' ,
            'j' , 'k' , 'm' , 'n' , 'p' , 'q' , 'r' , 's' , 't' , 'u' , 'v' , 'w' , 'x' ,
            'y' , 'z' , 'A' , 'B', 'C' , 'D' , 'E' , 'F' , 'G' , 'H' , 'J' , 'K' , 'L' , 'M' , 'N' ,
            'P' , 'Q' , 'R' , 'S' , 'T' , 'U' , 'V' , 'W' , 'X' , 'Y' , 'Z' , '1', '2' , '3' , '4' , '5' , '6' ,
            '7' , '8' , '9', '0'};

    @Autowired
    private JavaMailSender javaMailSender;

    @Autowired
    RegisterDao registerDao;

    @Override
    public boolean normalConsumer(Consumer consumer, String verifyCode, HttpSession session) throws SQLException, TeleNumberExistException, LoginException {
        if (session.getAttribute("EMail_dueTime") == null || LocalDateTime.parse(String.valueOf(session.getAttribute("EMail_dueTime")), DateTimeFormatter.ofPattern("yyyyMMddHHmm")).isBefore(LocalDateTime.now())){
            throw new LoginException("邮箱验证码失效");
        }
        if (!verifyCode.equals(session.getAttribute("EMail_verifyCode"))){
            throw new LoginException("邮箱验证码不正确");
        }
        if (!session.getAttribute("Email").equals(consumer.getEmail())){
            throw new LoginException("邮箱不匹配");
        }
        if (registerDao.findConsumerByAccountMember(consumer).size()>0) {
            throw new TeleNumberExistException();
        }
        session.removeAttribute("EMail_verifyCode");
        session.removeAttribute("EMail_dueTime");
        registerDao.addConsumer(consumer);
        return true;
    }

    @Override
    public boolean memberConsumer(Consumer consumer) throws SQLException {
        registerDao.updateByID(consumer);
        return true;
    }

    @Override
    public Consumer modifyPassword(Consumer consumer, String newPassword, String verifyCode, HttpSession session) throws LoginException, SQLException {
        if (session.getAttribute("EMail_dueTime") == null || LocalDateTime.parse(String.valueOf(session.getAttribute("EMail_dueTime")), DateTimeFormatter.ofPattern("yyyyMMddHHmm")).isBefore(LocalDateTime.now())){
            throw new LoginException("邮箱验证码失效");
        }
        if (!verifyCode.equals(session.getAttribute("EMail_verifyCode"))){
            throw new LoginException("邮箱验证码不正确");
        }
        Consumer oldConsumer = registerDao.findConsumerByAccountMember(consumer).get(0);
        if (!oldConsumer.getPassword().equals(consumer.getPassword())){
            throw new LoginException("旧密码不正确");
        }
        session.removeAttribute("EMail_verifyCode");
        session.removeAttribute("EMail_dueTime");
        oldConsumer.setPassword(newPassword);
        registerDao.updateByID(oldConsumer);
        return oldConsumer;
    }

    @Override
    public Boolean sendVerifyCode(Consumer consumer, HttpServletRequest request, HttpSession session) throws MailException, SQLException, NotMemberException, LoginException, ParametersIncompleteException {
        if (consumer.getAccountMember() != null){
            List<Consumer> consumers = registerDao.findConsumerByAccountMember(consumer);
            if (consumers.size() <= 0){
                NotMemberException notMemberException = new NotMemberException();
                notMemberException.setMessage("没有这个用户");
                throw notMemberException;
            }
            consumer.setEmail(consumers.get(0).getEmail());
        }
        return sendEmainCode(consumer, request, session);
    }

    @Override
    public Boolean authenticMember(Consumer consumer) throws SQLException {
        registerDao.updateByID(consumer);
        return true;
    }

    @Override
    public Consumer getInfoById(Consumer consumer) throws SQLException {
        return registerDao.selectConsumerById(consumer);
    }

    @Override
    public boolean modifyInfo(Consumer consumer) throws SQLException {
        registerDao.updateByID(consumer);
        return true;
    }


    private boolean sendEmainCode(Consumer consumer, HttpServletRequest request, HttpSession session) throws SQLException, LoginException, ParametersIncompleteException {
        if (registerDao.selectConsumerByEmail(consumer).size() > 0 && request.getRequestURI().toString().contains("register")){
            throw new LoginException("此邮箱已被注册过");
        }
        if (request.getRequestURI().toString().contains("modifyPassword")){
            if (consumer.getAccountMember() == null || consumer.getPassword() == null){
                throw new ParametersIncompleteException("账号与密码不完整");
            }
            ArrayList<Consumer> consumerByAccountMember = registerDao.findConsumerByAccountMember(consumer);
            if (consumerByAccountMember.size() <= 0){
                throw new LoginException("用户不存在");
            }
            if(!consumerByAccountMember.get(0).getPassword().equals(consumer.getPassword())){
                throw new LoginException("密码不正确");
            }
            consumer.setEmail(consumerByAccountMember.get(0).getEmail());
        }
        StringBuffer verifyCode = new StringBuffer();
        for (int i=0; i<7; i++)
            verifyCode.append(code[(int)(Math.random()*58)]);

        logger.info("给【" + consumer.getId() + "】, 邮箱【" + consumer.getEmail() +"】发验证码" );
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setSubject("登录验证码");
        simpleMailMessage.setText("你的验证码为:【" + verifyCode +"】. 有效时间5分钟. @CopyRight Mybatisers");
        simpleMailMessage.setFrom("515189195@qq.com");
        simpleMailMessage.setTo(consumer.getEmail());
        javaMailSender.send(simpleMailMessage);
        session.setAttribute("EMail_verifyCode", verifyCode.toString());
        session.setAttribute("EMail_dueTime", LocalDateTime.now().plusMinutes(10).format(DateTimeFormatter.ofPattern("yyyyMMddHHmm")));
        session.setAttribute("Email", consumer.getEmail());
        System.out.println("邮箱验证码" + verifyCode);
        return true;
    }

}
